<template>
  <div class="replica-group" :class="statusClass">
    <div class="group-header">
      <h3>Replica Group {{ group.id }}</h3>
      <span class="group-status">{{ groupStatusLabel }}</span>
      <div class="step-progress">
        <div class="progress-bar" :style="{ width: `${currentStepProgress}%` }"></div>
        <span>
          {{ statusMessage }}
          <span v-if="isLoading" class="loading-dots">...</span>
        </span>
      </div>
    </div>
    
    <div class="servers-container">
      <div v-for="server in groupServers" :key="server.id" class="server">
        <div class="server-header">
          <span class="server-id">{{ server.id }}</span>
          <span class="gpu-count">{{ server.gpus.length }}/8 GPUs</span>
        </div>
        <div class="gpus-grid">
          <GPUNode 
            v-for="gpu in server.gpus" 
            :key="gpu.id"
            :gpu="gpu"
            :loading="isLoading"
            @deactivate="deactivateGPU"
          />
        </div>
      </div>
    </div>
    
    <button 
      v-if="group.status === 'offline'"
      class="reactivate-btn"
      @click="reactivateGroup"
      :disabled="isLoading"
    >
      <span v-if="!isLoading">Reactivate Group</span>
      <span v-else class="loading-text">Reactivating</span>
    </button>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import { useTrainingStore } from '../stores/training'
import GPUNode from './GPUNode.vue'

const props = defineProps({
  group: {
    type: Object,
    required: true
  }
})

const emit = defineEmits(['deactivate-gpu', 'reactivate-group'])
const store = useTrainingStore()

const isLoading = computed(() => {
  return ['deactivating', 'activating'].includes(props.group.status)
})

const groupStatusLabel = computed(() => {
  return {
    training: 'Training',
    offline: 'Offline',
    deactivating: 'Deactivating...',
    activating: 'Activating...'
  }[props.group.status] || props.group.status
})

const statusClass = computed(() => {
  const baseStatus = props.group.status.replace(/ing$/, '') // 移除loading状态的ing后缀
  return `status-${baseStatus}`
})

const groupServers = computed(() => {
  const serverMap = {}
  
  // Group GPUs by server
  Object.values(props.group.gpus).forEach(gpu => {
    if (!serverMap[gpu.server]) {
      serverMap[gpu.server] = {
        id: gpu.server,
        gpus: []
      }
    }
    serverMap[gpu.server].gpus.push(gpu)
  })
  
  return Object.values(serverMap)
})

const currentStepProgress = computed(() => {
  // 如果处于offline状态，使用fixedStep的进度
  if (props.group.status === 'offline' && props.group.fixedStep !== undefined) {
    return props.group.fixedStep % 100
  }
  return props.group.stepProgress
})

const statusMessage = computed(() => {
  switch(props.group.status) {
    case 'training': 
      return `Step ${store.step} (${props.group.stepProgress}%)`;
    case 'deactivating': 
      return `Deactivating at step ${props.group.fixedStep || store.step}`;
    case 'activating': 
      return `Activating from step ${props.group.fixedStep || store.step}`;
    case 'offline': 
      return `Paused at step ${props.group.fixedStep}`;
    default: 
      return 'Paused';
  }
})

function deactivateGPU(gpuId) {
  emit('deactivate-gpu', gpuId)
}

function reactivateGroup() {
  emit('reactivate-group', props.group.id)
}
</script>

<style scoped>
.replica-group {
  background-color: white;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.status-training {
  border-left: 4px solid #52c41a;
}

.status-offline {
  border-left: 4px solid #ff4d4f;
  opacity: 0.8;
}

.group-header {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.group-header h3 {
  margin: 0;
  font-size: 1.1rem;
  color: #333;
}

.group-status {
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: 500;
  align-self: flex-start;
}

.status-training .group-status {
  background-color: #e6f7ff;
  color: #1890ff;
}

.status-offline .group-status {
  background-color: #fff2f0;
  color: #ff4d4f;
}

.step-progress {
  height: 24px;
  background-color: #f5f5f5;
  border-radius: 4px;
  position: relative;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background-color: #1890ff;
  transition: width 0.3s;
}

.step-progress span {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  color: #333;
  font-weight: 500;
}

.servers-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.server {
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  padding: 10px;
}

.server-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 0.9rem;
}

.server-id {
  font-weight: 500;
}

.gpu-count {
  color: #666;
}

.gpus-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
}

.reactivate-btn {
  align-self: flex-end;
  padding: 6px 12px;
  background-color: #1890ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.9rem;
}

.reactivate-btn:hover {
  background-color: #40a9ff;
}

.status-offline .step-progress {
  background-color: #f5f5f5;
}

.status-offline .step-progress .progress-bar {
  background-color: #d9d9d9;
}

.status-offline .step-progress span {
  color: #999;
}

.loading-dots {
  display: inline-block;
  width: 1em;
  text-align: left;
}

.loading-dots::after {
  content: '...';
  animation: dots 1.5s steps(5, end) infinite;
}

@keyframes dots {
  0%, 20% { content: '.'; }
  40% { content: '..'; }
  60%, 100% { content: '...'; }
}

.reactivate-btn .loading-text::after {
  content: '...';
  animation: dots 1.5s steps(5, end) infinite;
}

/* 添加状态颜色 */
.status-deactivating {
  border-left: 4px solid #faad14;
}

.status-activating {
  border-left: 4px solid #faad14;
}

/* 禁用状态的按钮 */
.reactivate-btn:disabled {
  background-color: #d9d9d9;
  cursor: not-allowed;
}

.status-offline .util-bar {
  width: 0% !important;
  background-color: #d9d9d9 !important;
  transition: width 0.5s ease-out;
}

.status-offline .gpu-chip {
  background-color: #d9d9d9 !important;
  transition: background-color 0.5s ease-out;
}

.status-offline .gpu-fan {
  animation: none !important;
}
</style>